import java.util.Vector;

import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PImage;
import TUIO.TuioCursor;
import TUIO.TuioObject;
import TUIO.TuioPoint;
import TUIO.TuioProcessing;
import TUIO.TuioTime;
import database.*;


public class TuioJavaProcessingExample extends PApplet{
	/**
	 * 
	 */
	private static final long serialVersionUID = 643795197348460651L;

	TuioProcessing tuioClient;

	// these are some helper variables which are used
	// to create scalable graphical feedback
	float cursor_size = 15;
	float object_size = 60;
	float table_size = 760;
	float scale_factor = 1;
	PFont font;
	
	// database
	DBConnector conn;
	
	// albums to work with
	AlbumCollection albumColl;
	
	// image to drag and drop
	//PImage a;
	//TuioPoint lastPoint;
	//boolean obj1Found;
	//float offsetX;
	//float offsetY;

	public void setup()
	{
		//size(screen.width,screen.height);
		size(640,480);
		noStroke();
		fill(0);
		
		loop();
		frameRate(30);
		//noLoop();

		hint(ENABLE_NATIVE_FONTS);
		font = createFont("Arial", 18);
		scale_factor = height/table_size;
		
		//database testing
		conn = new DBConnector(this);
		conn.doTests();
		conn.close();
		albumColl = conn.getAlbumCollection();
		
		
		// we create an instance of the TuioProcessing client
		// since we add "this" class as an argument the TuioProcessing class expects
		// an implementation of the TUIO callback methods (see below)
		tuioClient  = new TuioProcessing(this);
	}

	// within the draw method we retrieve a Vector (List) of TuioObject and TuioCursor (polling)
	// from the TuioProcessing client and then loop over both lists to draw the graphical feedback.
	public void draw()
	{
		background(255);
		textFont(font,18*scale_factor);
		float obj_size = object_size*scale_factor; 
		float cur_size = cursor_size*scale_factor; 

		Vector tuioObjectList = tuioClient.getTuioObjects();
		for (int i=0;i<tuioObjectList.size();i++) {
			TuioObject tobj = (TuioObject)tuioObjectList.elementAt(i);
			stroke(0);
			fill(0);
			pushMatrix();
			translate(tobj.getScreenX(width),tobj.getScreenY(height));
			rotate(tobj.getAngle());
			rect(-obj_size/2,-obj_size/2,obj_size,obj_size);
			popMatrix();
			fill(255);
			text(""+tobj.getSymbolID(), tobj.getScreenX(width), tobj.getScreenY(height));
			
			
		}

		Vector tuioCursorList = tuioClient.getTuioCursors();
		for (int i=0;i<tuioCursorList.size();i++) {
			TuioCursor tcur = (TuioCursor)tuioCursorList.elementAt(i);
			Vector pointList = tcur.getPath();

			if (pointList.size()>0) {
				stroke(0,0,255);
				TuioPoint start_point = (TuioPoint)pointList.firstElement();;
				for (int j=0;j<pointList.size();j++) {
					TuioPoint end_point = (TuioPoint)pointList.elementAt(j);
					line(start_point.getScreenX(width),start_point.getScreenY(height),end_point.getScreenX(width),end_point.getScreenY(height));
					start_point = end_point;
				}

				stroke(192,192,192);
				fill(192,192,192);
				//ellipse( tcur.getScreenX(width), tcur.getScreenY(height),cur_size,cur_size);
				//image(a, tcur.getScreenX(width), tcur.getScreenY(height));
				
				System.out.println("CURSORX: " + tcur.getScreenX(width));
				System.out.println("CURSORY: " + tcur.getScreenY(height));
				
				fill(0);
				for(int j = 0; j < albumColl.size(); ++j){
					if(albumColl.getAlbum(j).isObjMoving()){
						System.out.println("Obj1 found!!!");
						float offsetX = albumColl.getAlbum(j).getOffsetX();
						float offsetY = albumColl.getAlbum(j).getOffsetY();
						PImage a = albumColl.getAlbum(j).getImage();
						image(a, tcur.getScreenX(width)-offsetX, tcur.getScreenY(height)-offsetY);
						albumColl.getAlbum(j).setLastPoint(new TuioPoint(tcur.getScreenX(width)-offsetX, tcur.getScreenY(height)-offsetY));
					} else{
						PImage a = albumColl.getAlbum(j).getImage();
						image(a, albumColl.getAlbum(j).getLastPoint().getX(), albumColl.getAlbum(j).getLastPoint().getY());
						System.out.println("Obj1 not found...");
					}
				}
				
				text(""+ tcur.getCursorID(),  tcur.getScreenX(width)-5,  tcur.getScreenY(height)+5);
			}
		}
		for(int i = 0; i < albumColl.size(); ++i){
			if(!albumColl.getAlbum(i).isObjMoving()){
				PImage a = albumColl.getAlbum(i).getImage();
				image(a, albumColl.getAlbum(i).getLastPoint().getX(), albumColl.getAlbum(i).getLastPoint().getY());
				
			}
		}
		
		

	}

	// these callback methods are called whenever a TUIO event occurs

	// called when an object is added to the scene
	public void addTuioObject(TuioObject tobj) {
		println("add object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle());
	}

	// called when an object is removed from the scene
	public void removeTuioObject(TuioObject tobj) {
		println("remove object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+")");
	}

	// called when an object is moved
	public void updateTuioObject (TuioObject tobj) {
		println("update object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle()
				+" "+tobj.getMotionSpeed()+" "+tobj.getRotationSpeed()+" "+tobj.getMotionAccel()+" "+tobj.getRotationAccel());
	}

	// called when a cursor is added to the scene
	public void addTuioCursor(TuioCursor tcur) {
		println("add cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY());
		//check if cursor is in picture
		for(int i = 0; i < conn.getAlbumCollection().size(); ++i){
			float offsetX = tcur.getScreenX(width)  - albumColl.getAlbum(i).getLastPoint().getX();
			float offsetY = tcur.getScreenY(height) - albumColl.getAlbum(i).getLastPoint().getY();
			boolean obj1Found = false;
			PImage a = albumColl.getAlbum(i).getImage();
			if(	offsetX >= 0 &&
				offsetX <= (a.width) &&
				offsetY >= 0 &&
				offsetY <= (a.height)){
				obj1Found = true;
			}
			albumColl.getAlbum(i).setOffsetX(offsetX );
			albumColl.getAlbum(i).setOffsetY(offsetY);
			albumColl.getAlbum(i).setObjMoving(obj1Found);
		}
	}

	// called when a cursor is moved
	public void updateTuioCursor (TuioCursor tcur) {
		println("update cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY()
				+" "+tcur.getMotionSpeed()+" "+tcur.getMotionAccel());
	}

	// called when a cursor is removed from the scene
	public void removeTuioCursor(TuioCursor tcur) {
		println("remove cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+")");
		//obj1Found = false;
		for(int i = 0; i < albumColl.size(); ++i){
			if(albumColl.getAlbum(i).getCursorId() == tcur.getCursorID())
				albumColl.getAlbum(i).setObjMoving(false);
		}
	}

	// called after each message bundle
	// representing the end of an image frame
	public void refresh(TuioTime bundleTime) { 
		redraw();
	}

}
